package model.unit_tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import model.Library;
import model.QA;
import model.User;

import org.junit.Before;
import org.junit.Test;

public class LibraryTest {
	Library myLibrary;
	
	User myAdmin;
	User myWriter;
	
	QA mySample;
	QA mySSample;
	
	String myCategory;
	String myQuestion;
	String myAnswer;
	String myKeywords;
	
	String mySCategory;
	String mySQuestion;
	String mySAnswer;
	String mySKeywords;
	
	List<QA> expLinked;
	List<QA> expArray;

	@Before
	public void setUp() throws Exception {
		myLibrary = Library.createFromOriginal();
		myWriter = new User("NotTrent", "r123456", 11111, false);
		myAdmin = new User("Trent", "r624113", 11111, true);
		myLibrary.setUser(myWriter);
		
		myCategory = "Regulatory/Legal";
		myQuestion = "Disclosure of any legal claims or arbitration hearings involving the firm within the last five years.";
		myAnswer = "There have been no legal claims or arbitration hearings involving GBL.";
		myKeywords = "legal,claim,arbitration,firm";
		
		mySCategory = "Regulatory/Legal";
		mySQuestion = "What is the State of Incorporation and Governing Law of your agreements?";
		mySAnswer = "The State of Washington.";
		mySKeywords = "state of incorporation,govern,legal,agreement";
		
		mySample = new QA(myCategory, myQuestion, myAnswer, myKeywords);
		mySSample = new QA(mySCategory, mySQuestion, mySAnswer, mySKeywords);
		
		expLinked = new LinkedList<QA>();
		expArray = new ArrayList<QA>();
}

	@Test
	public void testSearchByKeyword() {
		myCategory = "Operations";
		myQuestion = "Can you provide us with a summary of your business continuity plan and disaster recovery plan?";
		myAnswer = "BUSINESS CONTINUITY AND DISASTER RECOVERY 24-HOUR IT SUPPORT-Data and applications that support "
				+ "the freight management team are backed up on a separate server in a separate location every 15 minutes. "
				+ "In the event that the server should fail completely (mechanical or viral), we can switch over to the "
				+ "alternative server with minimal interruption. BACK-UP POWER SOURCE-The buildings we operate from are "
				+ "supported by emergency generators which will provide uninterrupted power supply in the event of a failure "
				+ "of the primary electric power grid. REMOTE OPERATIONS-Members of the  management team are able to access the "
				+ "necessary Global Business Logistics servers from home. Further, we maintain a separate set of SecurID cards "
				+ "outside the office (these cards provide codes that, along with passwords, provide access to the various websites "
				+ "and custodian systems we retrieve data from). This would allow our team to fully function in the event that we "
				+ "could not access our building but the systems are still operational (e.g. extreme weather, natural disaster, "
				+ "damage to highways or bridges). This capability is tested quarterly with scheduled \"disaster recovery practice\" "
				+ "days. ALTERNATIVE WORK SITE-In the event that our systems and building are unavailable for an extended period of "
				+ "time, Global Business Logistics maintains a recovery site to support critical business functions.";
		myKeywords = "business continuity,disaster recovery,plan";
		
		mySample = new QA(myCategory, myQuestion, myAnswer, myKeywords);
		
		String keywordOne = "disaster recovery";
		String keywordTwo = "business continuity";
		expLinked.add(mySample);
		expArray.add(mySample);
		List<QA> fakeArrayList = new ArrayList<QA>();
		List<QA> fakeLinkList = new LinkedList<QA>();
		List<QA> result = myLibrary.searchByKeyword(keywordOne);
		
		assertEquals(expLinked, result);
		assertEquals(expArray, result);
		assertFalse(result.equals(fakeArrayList));
		assertFalse(result.equals(fakeLinkList));
		assertTrue(result.equals(expLinked));
		assertTrue(expLinked.equals(result));
		assertTrue(result.equals(expArray));
		assertTrue(expArray.equals(result));
		
		result = myLibrary.searchByKeyword(keywordTwo);
		assertTrue(result.equals(expLinked));
		assertTrue(expLinked.equals(result));
		assertTrue(result.equals(expArray));
		assertTrue(expArray.equals(result));
	}
	
	@Test
	public void testSearchByKeywordPartTwo() {
		String keywordOne = "disaster recovery";
		String keywordTwo = "business continuity";
		
		expLinked.add(mySample);
		expLinked.add(mySSample);
		expArray.add(mySample);
		expArray.add(mySSample);
		
		List<QA> fakeArrayList = new ArrayList<QA>();
		List<QA> fakeLinkList = new LinkedList<QA>();
		
		List<QA> result = myLibrary.searchByKeyword(keywordOne);
		
		assertEquals(expLinked, result);
		assertEquals(expArray, result);
		assertFalse(result.equals(fakeArrayList));
		assertFalse(result.equals(fakeLinkList));
		assertTrue(result.equals(expLinked));
		assertTrue(expLinked.equals(result));
		assertTrue(result.equals(expArray));
		assertTrue(expArray.equals(result));
		
		result = myLibrary.searchByKeyword(keywordTwo);
		assertTrue(result.equals(expLinked));
		assertTrue(expLinked.equals(result));
		assertTrue(result.equals(expArray));
		assertTrue(expArray.equals(result));
	}

	@Test
	public void testSearchByQuestion() {
		expLinked.add(mySample);
		expArray.add(mySSample);
		
		List<QA> resultA = myLibrary.searchByQuestion(myQuestion);
		List<QA> resultB = myLibrary.searchByQuestion(mySQuestion);
		
		assertEquals(expLinked, resultA);
		assertFalse(expArray.equals(resultA));
		
		assertEquals(expArray, resultB);
		assertFalse(expLinked.equals(resultB));
	}

	@Test
	public void testSearchByAnswer() {
		expLinked.add(mySample);
		expArray.add(mySSample);
		
		List<QA> resultA = myLibrary.searchByAnswer(myAnswer);
		List<QA> resultB = myLibrary.searchByAnswer(mySAnswer);
		
		assertEquals(expLinked, resultA);
		assertFalse(expArray.equals(resultA));
		
		assertEquals(expArray, resultB);
		assertFalse(expLinked.equals(resultB));
	}

	@Test
	public void testBrowseByCategory() {
		expLinked.add(mySample);
		expArray.add(mySSample);

		List<QA> resultA = myLibrary.browseByCategory(myCategory);
		List<QA> resultB = myLibrary.browseByCategory(mySCategory);

		assertTrue(resultA.contains(mySample));
		assertTrue(resultA.contains(mySSample));
		
		assertTrue(resultB.contains(mySSample));
		assertTrue(resultB.contains(mySample));
	}

	@Test
	public void testGetAvailableCatergories() {
		Set<String> available = myLibrary.getAvailableCatergories();
		Set<String> expected = new HashSet<String>();
		
		expected.add("Staff");
		expected.add("Regulatory/Legal");
		expected.add("Philosophy");
		expected.add("Ownership");
		expected.add("Operations");
		expected.add("History");
		expected.add("Background");
		
		assertTrue(available.containsAll(expected));
	}

	@Test
	public void testAddResponse() {
		fail("Not yet implemented");
	}

	@Test
	public void testRemoveResponse() {
		fail("Not yet implemented");
	}

	@Test
	public void testSerialization() {
		fail("Not yet implemented");
	}

}
